home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Bitmap / Sources / Frame.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  21.5 KB  |  738 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Frame.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "Bitmap.hpp"
  13.  
  14. #ifndef FRAME_H
  15. #include "Frame.h"
  16. #endif
  17.  
  18. #ifndef PART_H
  19. #include "Part.h"
  20. #endif
  21.  
  22. #ifndef CONTENT_H
  23. #include "Content.h"
  24. #endif
  25.  
  26. #ifndef SELECT_H
  27. #include "Select.h"
  28. #endif
  29.  
  30. #ifndef RBBRBAND_H
  31. #include "RbbrBand.h"
  32. #endif
  33.  
  34. #ifndef DEFINES_K
  35. #include "Defines.k"
  36. #endif
  37.  
  38. // ----- Part Layer -----
  39.  
  40. #ifndef FWCLPCMD_H
  41. #include "FWClpCmd.h"
  42. #endif
  43.  
  44. #ifndef FWKIND_H
  45. #include "FWKind.h"
  46. #endif
  47.  
  48. #ifndef FWDRCMD_H
  49. #include "FWDrCmd.h"
  50. #endif
  51.  
  52. #ifndef FWUTIL_H
  53. #include "FWUtil.h"
  54. #endif
  55.  
  56. #ifndef FWPRTITE_H
  57. #include "FWPrtIte.h"
  58. #endif
  59.  
  60. #ifndef FWGROWBX_H
  61. #include "FWGrowBx.h"
  62. #endif
  63.  
  64. #ifndef FWSCLBAR_H
  65. #include "FWSclBar.h"
  66. #endif
  67.  
  68. #ifndef FWPRESEN_H
  69. #include "FWPresen.h"
  70. #endif
  71.  
  72. #ifndef FWITERS_H
  73. #include "FWIters.h"
  74. #endif
  75.  
  76. #ifndef FWIDLE_H
  77. #include "FWIdle.h"
  78. #endif
  79.  
  80. #ifndef FWCONTXT_H
  81. #include "FWContxt.h"
  82. #endif
  83.  
  84. // ----- OS Layer -----
  85.  
  86. #ifndef FWODGEOM_H
  87. #include "FWODGeom.h"
  88. #endif
  89.  
  90. #ifndef FWBMPSHP_H
  91. #include "FWBmpShp.h"
  92. #endif
  93.  
  94. #ifndef FWEVENT_H
  95. #include "FWEvent.h"
  96. #endif
  97.  
  98. #ifndef FWSUSINK_H
  99. #include "FWSUSink.h"
  100. #endif
  101.  
  102. #ifndef SLMixOS_H
  103. #include "SLMixOS.h"
  104. #endif
  105.  
  106. // ----- ColorExtension Includes -----
  107.  
  108. #ifndef CECLIENT_H
  109. #include "CEClient.h"
  110. #endif
  111.  
  112. // ----- OpenDoc Includes -----
  113.  
  114. #ifndef SOM_Module_OpenDoc_StdProps_defined
  115. #include <StdProps.xh>
  116. #endif
  117.  
  118. #ifndef SOM_ODDragItemIterator_xh
  119. #include <DgItmIt.xh>
  120. #endif
  121.  
  122.  
  123. // ----- Cyberdog Support -----
  124.  
  125. #if FW_SUPPORTS_CYBERDOG
  126.  
  127. #ifndef __CYBERDOG__
  128. #include <Cyberdog.h>
  129. #endif
  130.  
  131. #ifndef SOM_CyberServiceMenu_xh
  132. #include <CyberServiceMenu.xh>
  133. #endif
  134.  
  135. #ifndef SOM_CyberSession_xh
  136. #include <CyberSession.xh>
  137. #endif
  138.  
  139. #ifndef FWEXTMGR_H
  140. #include "FWExtMgr.h"
  141. #endif
  142.  
  143. #ifndef FWCYPART_H
  144. #include "FWCyPart.h"
  145. #endif
  146.  
  147. #endif // FW_SUPPORTS_CYBERDOG
  148.  
  149. //========================================================================================
  150. //    Runtime Informations
  151. //========================================================================================
  152.  
  153. #ifdef FW_BUILD_MAC
  154. #pragma segment odfbitmap
  155. #endif
  156.  
  157. //========================================================================================
  158. //    class CBitmapFrame
  159. //========================================================================================
  160.  
  161. FW_DEFINE_AUTO(CBitmapFrame)
  162.     
  163. //----------------------------------------------------------------------------------------
  164. //    CBitmapFrame::CBitmapFrame
  165. //----------------------------------------------------------------------------------------
  166. //    CBitmapFrame constructor
  167.  
  168. CBitmapFrame::CBitmapFrame(Environment* ev, ODFrame* odFrame, FW_CPresentation* presentation, CBitmapPart* bitmapPart, CBitmapContent* content) :
  169.     FW_CFrame(ev, odFrame, presentation, bitmapPart),
  170.     FW_MDroppableFrame(ev, this),
  171.     FW_MDraggableFrame(ev, this),
  172.     fBitmapContent(content),
  173.     fChosenSize(cFitToFrame),
  174.     fSelection((CBitmapSelection*)presentation->GetSelection(ev)),
  175.     fIdler(NULL)
  176. {    
  177.     if (IsRoot(ev))
  178.         fChosenSize = cRealSize;
  179.         
  180.     // ----- Save my current frame rect -----
  181.     fFrameRect = this->GetBounds(ev);
  182.         
  183.     fIdler = FW_NEW(FW_CIdler, (this, 15));
  184.     
  185.     // ----- I want to be able to drop even in thumbnail mode -----
  186.     ChangeDroppableState(ev, FW_kFrameDroppable | FW_kThumbnailDroppable);
  187.     
  188.     FW_END_CONSTRUCTOR
  189. }
  190.  
  191. //----------------------------------------------------------------------------------------
  192. //    CBitmapFrame::~CBitmapFrame
  193. //----------------------------------------------------------------------------------------
  194. //    CBitmapFrame destructor
  195.  
  196. CBitmapFrame::~CBitmapFrame()
  197. {
  198.     FW_START_DESTRUCTOR
  199.     
  200.     delete fIdler;
  201.     fIdler = NULL;
  202. }
  203.  
  204. //----------------------------------------------------------------------------------------
  205. //    CBitmapFrame::DoAdjustMenus
  206. //----------------------------------------------------------------------------------------
  207. //    ODF Method
  208.  
  209. FW_Handled CBitmapFrame::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  210. {
  211. FW_UNUSED(isRoot);
  212.     if (hasMenuFocus)
  213.     {
  214.         // ----- OpenDoc Items -----    
  215.         FW_Boolean canPaste = HasSupportedKindOnClipboard(ev) && !GetPart(ev)->IsReadOnly(ev);
  216.             
  217.         menuBar->EnableCommand(ev, kODCommandSelectAll, TRUE);                        // Allow Select All
  218.         menuBar->EnableCommand(ev, kODCommandClear, FALSE);                            // Don't allow Clear
  219.         menuBar->EnableCommand(ev, kODCommandCut, FALSE);                            // Don't allow cut                        
  220.         menuBar->EnableCommand(ev, kODCommandCopy, !fSelection->IsEmpty(ev));        // Allow copy only if my selection is not empty
  221.         menuBar->EnableCommand(ev, kODCommandPaste, canPaste);                        // Allow Paste if right property on the clipboard
  222.         menuBar->EnableCommand(ev, kODCommandPasteAs, FALSE);                        // Don't allow Past As for now
  223.         
  224.         // ----- My Items -----
  225.         ODCommandID choosenSize = GetChosenSize();
  226.         
  227.         menuBar->EnableAndCheckCommand(ev, cHalfSize, TRUE, fChosenSize == cHalfSize);    
  228.         menuBar->EnableAndCheckCommand(ev, cRealSize, TRUE, fChosenSize == cRealSize);
  229.         menuBar->EnableAndCheckCommand(ev, cDoubleSize, TRUE, fChosenSize == cDoubleSize);
  230.         menuBar->EnableAndCheckCommand(ev, cFitToFrame, TRUE, fChosenSize == cFitToFrame);
  231.         menuBar->EnableCommand(ev, cRequestFrame, !IsRoot(ev));
  232.         menuBar->EnableCommand(ev, cRemoveFrame, IsRequestedFrame(ev));
  233.     }
  234.     
  235.     return FW_kNotHandled;
  236. }
  237.  
  238. //----------------------------------------------------------------------------------------
  239. //    CBitmapFrame::DoMenu
  240. //----------------------------------------------------------------------------------------
  241. // ODF method
  242.  
  243. FW_Handled CBitmapFrame::DoMenu(Environment* ev, const FW_CMenuEvent& theMenuEvent)
  244. {
  245.     FW_Handled result = FW_kHandled;
  246.     ODCommandID commandID = theMenuEvent.GetCommandID(ev);
  247.  
  248.     FW_CPresentation* myPresentation = GetPresentation(ev);
  249.     
  250.     switch (commandID)
  251.     {
  252.         case cHalfSize:
  253.         case cRealSize:
  254.         case cDoubleSize:
  255.         case cFitToFrame:
  256.             if (commandID != fChosenSize)
  257.             {
  258.                 fChosenSize = commandID;
  259.                 AdjustFrameSize(ev);
  260.             }
  261.             break;
  262.  
  263.         case cRequestFrame:
  264.             {
  265.                 FW_CAcquiredODShape aqShape = FW_CopyAndRelease(ev, AcquireFrameShape(ev));
  266.                 ODID sequence = myPresentation->RequestSiblingFrame(ev, this, aqShape, GetViewType(ev), FALSE);
  267.                 if (sequence != kODNULLID)
  268.                     myPresentation->Invalidate(ev, NULL, sequence);    // invalidate all frames of this sequence
  269.             }
  270.             break;
  271.  
  272.         case cRemoveFrame:
  273.             myPresentation->RemoveSiblingFrame(ev, this);
  274.             break;
  275.             
  276.         default:        
  277.             result = FW_kNotHandled;
  278.     }
  279.  
  280.     return result;
  281. }
  282.  
  283. //----------------------------------------------------------------------------------------
  284. //    CBitmapFrame::DoIdle
  285. //----------------------------------------------------------------------------------------
  286.  
  287. FW_Handled CBitmapFrame::DoIdle(Environment* ev, const FW_CNullEvent& theNullEvent)
  288. {
  289. FW_UNUSED(theNullEvent);    
  290.     if (fSelection != NULL && !fSelection->IsEmpty(ev))
  291.         fSelection->MoveAnts(ev, this);
  292.     
  293.     return FW_kHandled;
  294. }
  295.  
  296. //----------------------------------------------------------------------------------------
  297. //    CBitmapFrame::AdjustFrameSize
  298. //----------------------------------------------------------------------------------------
  299.  
  300. void CBitmapFrame::AdjustFrameSize(Environment* ev)
  301. {
  302.     if (IsRoot(ev))
  303.         UpdateUsedAndActiveShapes(ev);
  304.     else
  305.     {
  306.         FW_CRect usedRect;
  307.         CalcUsedRect(ev, usedRect);
  308.         usedRect.Place(FW_kZeroPoint);
  309.     
  310.         FW_CAcquiredODShape aqAskedFrameShape = ::FW_NewODShape(ev, usedRect);
  311.         FW_CAcquiredODShape aqFrameShape = AcquireFrameShape(ev);
  312.         
  313.         if (aqAskedFrameShape->IsSameAs(ev, aqFrameShape))
  314.             UpdateUsedAndActiveShapes(ev);
  315.         else
  316.             this->RequestFrameShape(ev, aqAskedFrameShape);
  317.     }
  318.     
  319.     this->Invalidate(ev);
  320. }
  321.  
  322. //----------------------------------------------------------------------------------------
  323. //    CBitmapFrame::FocusStateChanged
  324. //----------------------------------------------------------------------------------------
  325.  
  326. void CBitmapFrame::FocusStateChanged(Environment* ev, ODTypeToken focus, FW_Boolean newState, ODFrame* newOwner)
  327. {    
  328.     FW_CFrame::FocusStateChanged(ev, focus, newState, newOwner);
  329.  
  330.     if (focus == FW_CPart::fgSelectionFocusToken)
  331.     {
  332.         if (!fSelection->IsEmpty(ev))
  333.             fSelection->DrawAnts(ev, this);
  334.         
  335.         fIdler->RegisterIdle(ev, newState);
  336.     }
  337. }
  338.  
  339. //----------------------------------------------------------------------------------------
  340. //    CBitmapFrame::HandleWindowEvent
  341. //----------------------------------------------------------------------------------------
  342.  
  343. #if FW_SUPPORTS_CYBERDOG
  344. FW_Handled CBitmapFrame::HandleWindowEvent (Environment* ev, const FW_CMacWindowEvent& windowEvent)
  345. {
  346.     // ----- Cyberdog Support -----
  347.     // Sorry about this mess. At some point this code may be moved into 
  348.     // FW_CFrame or someplace similar. Basically we're implementing the Cyberdog 
  349.     // recipe for handling window-closing (it's different than normal OpenDoc
  350.     // window-closing). You can just copy this code into your Frame subclass.
  351.     
  352.     FW_Handled handled = FW_kNotHandled;
  353.     
  354.     if (windowEvent.GetMessage() == inGoAway) {
  355.         FW_CExtensionManager* manager = GetPart(ev)->GetExtensionManager(ev);
  356.         FW_ASSERT (manager);
  357.         ODExtension* extension = manager->AcquireExtension (ev, kCyberPartExtension, FW_kDontCreateExtension);
  358.         if (extension) {
  359.             CyberPartExtension* cextension = (CyberPartExtension*) extension;
  360.             CyberSession* cyberSession = cextension->GetCyberSession (ev);
  361.             FW_ASSERT (cyberSession);
  362.             if (cyberSession && cyberSession->CloseCyberDraftWindow (ev, GetPart(ev)->GetODPart(ev)))
  363.                 handled = FW_kHandled;
  364.         }
  365.     }
  366.     
  367.     if (handled == FW_kNotHandled)
  368.         handled = FW_CFrame::HandleWindowEvent (ev, windowEvent);
  369.     
  370.     return handled;
  371. }
  372. #endif
  373.  
  374. //----------------------------------------------------------------------------------------
  375. //    CBitmapFrame::FrameShapeChanged
  376. //----------------------------------------------------------------------------------------
  377.  
  378. void CBitmapFrame::FrameShapeChanged(Environment* ev)
  379. {    
  380.     FW_CFrame::FrameShapeChanged(ev);
  381.  
  382.     Invalidate(ev);        // redraw the whole frame
  383. }
  384.  
  385. //----------------------------------------------------------------------------------------
  386. //    CBitmapFrame::BuildThumbnail
  387. //----------------------------------------------------------------------------------------
  388. //    I just render the bitmap. I want to use the full 64*64
  389.  
  390. void CBitmapFrame::BuildThumbnail(Environment* ev, FW_CGraphicContext& gc, FW_CRect& usedRect)
  391. {
  392.     FW_CBitmap bitmap = fBitmapContent->GetBitmap(ev);    
  393.     FW_CBitmapShape::RenderBitmap(gc, bitmap, usedRect);
  394. }
  395.  
  396. //----------------------------------------------------------------------------------------
  397. //    CBitmapFrame::NewClipboardCommand
  398. //----------------------------------------------------------------------------------------
  399.  
  400. FW_CClipboardCommand* CBitmapFrame::NewClipboardCommand(Environment* ev, ODCommandID commandID)
  401. {
  402.     return FW_NEW(FW_CClipboardCommand, (ev,
  403.                                         commandID,
  404.                                          this,
  405.                                          FW_kCantUndo));
  406. }
  407.  
  408. //----------------------------------------------------------------------------------------
  409. //    CBitmapFrame::AdjustUsedShape
  410. //----------------------------------------------------------------------------------------
  411. // This Bitmap sample may draw in an area smaller than the frame shape. We let OpenDoc
  412. // know what shape is actually used so that containers of Bitmap can draw outside.
  413. // suggestedUsedShape is equal to the frame shape on entry.
  414.  
  415. ODShape* CBitmapFrame::AdjustUsedShape(Environment* ev, ODShape* suggestedUsedShape)
  416. {
  417.     // [LSD] OpenDoc bug or feature?  Do not make the used shape smaller than the frame
  418.     // shape in the case of root frames! Otherwise, since the active shape will be set
  419.     // to the used shape by default, mouse events won't be processed outside this shape.
  420.     
  421.     if (!IsRoot(ev))
  422.     {
  423.     FW_CRect usedShapeRect;
  424.     CalcUsedRect(ev, usedShapeRect);
  425.     
  426.     FW_CRect frameRect = GetBounds(ev);
  427.     usedShapeRect.Intersection(frameRect);
  428.     
  429.     ODRect odUsedShapeRect = usedShapeRect;
  430.     suggestedUsedShape->SetRectangle(ev, &odUsedShapeRect);
  431.     
  432.         // Must acquire it because I am reusing the shape passed as parameter
  433.         suggestedUsedShape->Acquire(ev);    
  434.         return suggestedUsedShape;
  435.     }
  436.     else
  437.         return NULL;    // use the frame shape for root frames
  438. }
  439.  
  440. //----------------------------------------------------------------------------------------
  441. //    CBitmapFrame::AdjustActiveShape
  442. //----------------------------------------------------------------------------------------
  443. // AdjustActiveShape must also be implemented whenever AdjustUsedShape is, otherwise
  444. // OpenDoc will use the frame shape by default, and we want the used shape to the default
  445. // active shape.
  446.  
  447. ODShape* CBitmapFrame::AdjustActiveShape(Environment* ev, ODFacet* facet, ODShape* suggestedActiveShape)
  448. {
  449. FW_UNUSED(facet);
  450.     // Root frames should not use a smaller active shape. See comments in AdjustUsedShape
  451.     
  452.     if (!IsRoot(ev))
  453.     {
  454.         // suggestedActiveShape is a copy of the used shape (in FW_CFrame::UpdateActiveShape)
  455.         // We tell OpenDoc that we're going to use it.
  456.         suggestedActiveShape->Acquire(ev);
  457.         return suggestedActiveShape;
  458.     }
  459.     else
  460.         return NULL;    // use the frame shape for root frames
  461. }
  462.  
  463. //----------------------------------------------------------------------------------------
  464. //    CBitmapFrame::AdjustZoomedWindowSize
  465. //----------------------------------------------------------------------------------------
  466.  
  467. void CBitmapFrame::AdjustZoomedWindowSize(Environment *ev, FW_CPoint& proposedSize)
  468. {
  469.     FW_CRect usedShapeRect;
  470.     CalcUsedRect(ev, usedShapeRect);
  471.     
  472.     proposedSize.Set(usedShapeRect.Width() + FW_IntToFixed(10), usedShapeRect.Height() + FW_IntToFixed(10));
  473. }
  474.  
  475. //----------------------------------------------------------------------------------------
  476. //    CBitmapFrame::GetZoomRatio
  477. //----------------------------------------------------------------------------------------
  478.  
  479. FW_CPoint CBitmapFrame::GetZoomRatio(Environment* ev) const
  480. {
  481.     FW_CBitmap bitmap = fBitmapContent->GetBitmap(ev);
  482.     FW_CRect bounds;
  483.     bitmap.GetBitmapBounds(bounds);
  484.     
  485.     FW_CRect usedRect;
  486.     CalcUsedRect(ev, usedRect);
  487.     
  488.     FW_CPoint ratio(
  489.         (usedRect.right - usedRect.left) / bounds.right, 
  490.         (usedRect.bottom - usedRect.top) / bounds.bottom);
  491.     
  492.     return ratio;
  493. }
  494.  
  495. //----------------------------------------------------------------------------------------
  496. //    CBitmapFrame::Draw
  497. //----------------------------------------------------------------------------------------
  498.  
  499. void CBitmapFrame::Draw(Environment* ev, ODFacet* odFacet, ODShape* invalidShape)
  500. {        
  501.     FW_CViewContext vc(ev, this, odFacet, invalidShape);
  502.     
  503.     // ------ [HLX] Will be moved to an adorner
  504.     if (IsTopFrame(ev))
  505.     {
  506.         FW_CRect invalidRect;
  507.         vc.GetClipRect(invalidRect);
  508.  
  509. #ifdef FW_BUILD_MAC
  510.         FW_CInk ink(FW_kRGBWhite,
  511.                     FW_kRGBWhite,
  512.                     FW_kErase);
  513. #else
  514.         FW_CInk ink(FW_CColor(::GetSysColor(COLOR_WINDOWTEXT), 0),
  515.                     FW_CColor(::GetSysColor(COLOR_APPWORKSPACE), 0),
  516.                     FW_kErase);
  517. #endif
  518.         FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, ink);
  519.     }
  520.  
  521.     FW_CRect usedRect;
  522.     CalcUsedRect(ev, usedRect);
  523.     
  524.     // ----- Use the static rendering method -----
  525.     // MacOS does nice dithering for us, so we always use a 16-bit deep bitmap
  526.     // and let QuickDraw dither. Windows requires us to decode and dither
  527.     // the image into a screen-depth bitmap.
  528. #ifdef FW_BUILD_MAC
  529.     FW_CBitmapShape::RenderBitmap (vc, fBitmapContent->GetBitmap(ev), usedRect, ditherCopy);
  530. #else
  531.     FW_CBitmapShape::RenderBitmap (vc, fBitmapContent->GetBitmap(ev), usedRect);
  532. #endif
  533.  
  534.     // ----- Draw the ants if there is a selection -----
  535.     if (HasSelectionFocus(ev) && !fSelection->IsEmpty(ev))
  536.     {
  537.         fSelection->DoDrawAnts(ev, vc, this);
  538.     }
  539. }
  540.  
  541. //----------------------------------------------------------------------------------------
  542. //    CBitmapFrame::CalcUsedRect
  543. //----------------------------------------------------------------------------------------
  544.  
  545. void CBitmapFrame::CalcUsedRect(Environment* ev, FW_CRect& newUsedRect) const
  546. {
  547.     ODCommandID choosenSize = GetChosenSize();
  548.     
  549.     FW_CRect frameRect = GetBounds(ev);
  550.     frameRect.Place(FW_kZeroPoint);
  551.     
  552.     if (choosenSize == cFitToFrame)
  553.     {
  554.         newUsedRect = frameRect;
  555.     }
  556.     else
  557.     {    
  558.         fBitmapContent->GetBitmap(ev).GetBitmapBounds(newUsedRect);    // return in 72 dpi
  559.         
  560.         if (choosenSize == cHalfSize)
  561.         {
  562.             newUsedRect.right   = FW_Half(newUsedRect.right);
  563.             newUsedRect.bottom  = FW_Half(newUsedRect.bottom);
  564.         }
  565.         else if (choosenSize == cDoubleSize)
  566.         {
  567.             newUsedRect.right   = FW_MultipliedByInt(newUsedRect.right,  2);
  568.             newUsedRect.bottom  = FW_MultipliedByInt(newUsedRect.bottom, 2);
  569.         }
  570.         
  571.         newUsedRect.PlaceInCenterOf(frameRect);
  572.     }
  573. }
  574.  
  575. //----------------------------------------------------------------------------------------
  576. //    CBitmapFrame::SetContainingPartColor
  577. //----------------------------------------------------------------------------------------
  578.  
  579. void CBitmapFrame::SetContainingPartColor(Environment* ev, 
  580.                                         const FW_CPoint& mousePoint) const
  581. {
  582.     if (!IsRoot(ev))
  583.     {
  584.         FW_CAcquiredODFrame frame = AcquireContainingFrame(ev);
  585.         if (frame != NULL)
  586.         {
  587.             FW_CAcquiredODPart acquiredPart = frame->AcquirePart(ev);
  588.             if (acquiredPart != NULL)
  589.             {
  590.                 if (acquiredPart->HasExtension(ev, CE_kColorExtensionName))
  591.                 {
  592.                     CE_CAcquiredColorExtension ce = (CE_OColorExtension*)acquiredPart->AcquireExtension(ev, CE_kColorExtensionName);
  593.                     
  594.                         // mouse point is in frame coordinates, which may not map
  595.                         // to bitmap coordinates as a consequence of scaling
  596.                     FW_CBitmap bitmap = fBitmapContent->GetBitmap(ev);
  597.                     FW_CRect sourceRect;    // frame geometry
  598.                     FW_CRect destRect;        // bitmap geometry
  599.                     FW_CPoint mappedPoint = mousePoint;
  600.  
  601.                     CalcUsedRect(ev, sourceRect);
  602.                     bitmap.GetBitmapBounds(destRect);
  603.                     mappedPoint.Map(sourceRect, destRect);
  604.                     
  605.                     FW_CColor pixelColor;
  606.                     unsigned short r, g, b;
  607.  
  608.                     bitmap.GetPixelColor(mappedPoint.IntX(), mappedPoint.IntY(), pixelColor);
  609.                     
  610.                     pixelColor.GetRGB(r, g, b);
  611.                     ce->SetForegroundColor(ev, r, g, b);
  612.                 }
  613.             }
  614.         }
  615.     }    
  616. }
  617.  
  618. //----------------------------------------------------------------------------------------
  619. //    CBitmapFrame::DoMouseDown
  620. //----------------------------------------------------------------------------------------
  621.  
  622. FW_Handled CBitmapFrame::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  623. {    
  624.     if (fSelection->IsMouseInDraggableItem(ev, this, theMouseEvent, FALSE))
  625.     {
  626.         if (!Drag(ev, theMouseEvent))
  627.             fSelection->CloseSelection(ev);
  628.     }
  629.     else
  630.     {
  631.         fSelection->CloseSelection(ev);
  632.         
  633.         FW_CRect usedRect;
  634.         CalcUsedRect(ev, usedRect);
  635.         
  636.          FW_CPoint where = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
  637.         FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, theMouseEvent.GetFacet(ev)->GetFrame(ev));
  638.         frame->GetContentView(ev)->FrameToViewContent(ev, where);
  639.         
  640.         SetContainingPartColor(ev, where);
  641.         
  642.         if (usedRect.Contains(where))
  643.         {
  644.             // ----- start a track -----
  645.             CRectRubberBand rubberBand(ev, this, theMouseEvent.GetFacet(ev), usedRect, GetZoomRatio(ev));
  646.         
  647.             if (rubberBand.Track(ev, theMouseEvent))
  648.             {
  649.                 FW_CRect rect;
  650.                 rubberBand.GetRect(rect);
  651.                 
  652.                 // ----- Apply the zoom ratio ----
  653.                 fSelection->SetSelectRect(GetZoomRatio(ev), usedRect, rect);
  654.                 fSelection->DrawAnts(ev, this);
  655.             }
  656.         }
  657.         else
  658.             FW_Beep();
  659.     }        
  660.  
  661.     return FW_kHandled;
  662. }
  663.  
  664. //----------------------------------------------------------------------------------------
  665. // CBitmapFrame::CreateSubViews
  666. //----------------------------------------------------------------------------------------
  667.  
  668. void CBitmapFrame::CreateSubViews(Environment* ev)
  669. {
  670.     // ----- Create a GrowBox only for root frames
  671.     //        (see Form or Container samples for declaring the grow-box in resources)
  672.     
  673.     if (IsRoot(ev))
  674.     {        
  675.         FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  676.     
  677.         FW_CRect frameRect = this->GetBounds(ev);
  678.         frameRect.bottom -= sbSize.y;
  679.         frameRect.right -= sbSize.x;
  680.         
  681.         FW_CGrowBox* growBox = new FW_CGrowBox(ev, this, 0, frameRect[FW_kBotRight]);
  682.     }
  683. }
  684.  
  685. //----------------------------------------------------------------------------------------
  686. //    CBitmapFrame::ExternalizeFrame
  687. //----------------------------------------------------------------------------------------
  688.  
  689. void CBitmapFrame::ExternalizeFrame(Environment* ev, ODStorageUnitView* storageUnitView)
  690. {
  691.     FW_CFrame::ExternalizeFrame(ev, storageUnitView);
  692.  
  693.     FW_PStorageUnitSink suSink(ev, storageUnitView);
  694.     FW_CWritableStream stream(suSink);
  695.     stream << fChosenSize;
  696. }
  697.  
  698. //----------------------------------------------------------------------------------------
  699. //    CBitmapFrame::InternalizeFrame
  700. //----------------------------------------------------------------------------------------
  701.  
  702. void CBitmapFrame::InternalizeFrame(Environment* ev, ODStorageUnitView* storageUnitView)
  703. {
  704.     FW_CFrame::InternalizeFrame(ev, storageUnitView);
  705.     
  706.     FW_PStorageUnitSink suSink(ev, storageUnitView);
  707. //    FW_PBufferedSink sink(ev, suSink);
  708.     FW_CReadableStream stream(suSink);
  709.     stream >> fChosenSize;
  710. }
  711.  
  712. //----------------------------------------------------------------------------------------
  713. //    CBitmapFrame::NewDragCommand
  714. //----------------------------------------------------------------------------------------
  715.  
  716. FW_CDragCommand* CBitmapFrame::NewDragCommand(Environment *ev, 
  717.                                     FW_CFrame* theFrame,
  718.                                     const FW_CMouseEvent& theMouseEvent)
  719. {
  720. FW_UNUSED(theMouseEvent);
  721.  
  722.     return FW_NEW(FW_CDragCommand, (ev, theFrame, FW_kCantUndo));
  723. }
  724.  
  725. //----------------------------------------------------------------------------------------
  726. //    CBitmapFrame::NewDropCommand
  727. //----------------------------------------------------------------------------------------
  728.  
  729. FW_CDropCommand* CBitmapFrame::NewDropCommand(Environment *ev, 
  730.                                     FW_CFrame* frame,
  731.                                     ODDragItemIterator* dropInfo, 
  732.                                     ODFacet* facet, 
  733.                                     const FW_CPoint& dropPoint)
  734. {
  735.  
  736.     return FW_NEW(FW_CDropCommand, (ev, frame, dropInfo, facet, dropPoint, FW_kCantUndo));
  737. }
  738.